﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rappelz.GameServer
{
    public class NPCRespawnObject : BaseObject
    {

//         BaseClass      :   StructNPC::NPCDeadHandler, offset = 0x40
//         VTable         :     , Type:  *
//         Function       :     public void onNPCDead(struct StructNPC *)
//         Function       :     public void NPCDeadHandler(const struct StructNPC::NPCDeadHandler &)
//         Function       :     public void NPCDeadHandler()
//         Function       :     public struct StructNPC::NPCDeadHandler & operator=(const struct StructNPC::NPCDeadHandler &)
// 
//         Function       :   public void NPCRespawnObject(const struct NPCRespawnObject &)
//         Function       :   public void NPCRespawnObject::NPCRespawnObject()
//         Function       :   public void NPCRespawnObject::onNPCDead(struct StructNPC *)

        public void Init()
        {
            RappelzServer.Instance.SetObjectPriority(this, Priority.Normal);
        }
//         Function       :   public bool NPCRespawnObject::ProcDelete()

        public void AddNPCRespawn(NPC npc)
        {
            lock(m_vNPCRespawnInfo)
            {
                m_vNPCRespawnInfo.Add(npc);
            }
        }

        public override void onProcess(int nThreadIdx)
        {
            uint t = Globals.GetArTime();

            lock(m_vNPCRespawnInfo)
            {
                for(int i = this.m_vNPCRespawnInfo.Count-1; i >= 0;--i)
                {
                    NPC npc = this.m_vNPCRespawnInfo[i];
                    if (npc.m_BaseInfo.is_periodic)
                    {
                        if (npc.m_BaseInfo.end_of_period <= t)
                        {
                            RappelzServer.Instance.DeleteObject(npc);
                            this.m_vNPCRespawnInfo.RemoveAt(i);
                            continue;
                        }
                        else if (npc.m_BaseInfo.end_of_period > t)
                        {
                            continue;
                        }
                    }
                    uint respawn_time = (uint)(npc.m_nDeadTime + npc.m_BaseInfo.regen_time);
                    if (respawn_time <= t)
                    {
//                        npc.m_pDeadHandler = this.m_pDeadHandler;
                        npc.SetCurrentXY(npc.m_BaseInfo.x, npc.m_BaseInfo.y);
                        npc.SetHP(npc.m_nMaxHP);
                        npc.SetStatus(0);

//                        buf[56] = LODWORD(v22->end.x);
//                        buf[55] = &result;

//                         v24 = RappelzServer.Instance._LockObjectWithVisibleRange(buf[55],buf[56]);
//                         ArcadiaAutoLock::ArcadiaAutoLock(&_lock, v24, buf[59], &buf[60]->handle);
//                         LOBYTE(v39) = 1;
//                         buf[60] = LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x);
                        GameContent.AddNPCToWorld(npc);
//                         LOBYTE(v39) = 0;
//                         ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
//                         v9 = &v30;
                        this.m_vNPCRespawnInfo.RemoveAt(i);
                    }
                }
            }
            RappelzServer.Instance.SetObjectPriority(this, Priority.Idle);
        }

        public List<NPC> m_vNPCRespawnInfo = new List<NPC>();                       // 0x44
//         Data           :   this+0x54, Member, Type: class XCriticalSection, m_CS
//         UserDefinedType:     XCriticalSection
// 
//         Function       :   public void NPCRespawnObject::~NPCRespawnObject()
//         Function       :   public struct NPCRespawnObject & operator=(const struct NPCRespawnObject &)
//         Function       :   public void __local_vftable_ctor_closure()
//         Function       :   public void * __vecDelDtor(unsigned int)

    }
}
